import { onUnmounted } from "vue"
import { event } from "./event"

// 处理各种按钮的操作
export function handleButton(data, foucsData) {
    // 记录拖动之前的 状态
    let beforeDrag = null
    // 定义操作的状态
    const operationState = {
        index: -1, // 前进后退的索引值
        queue: [], // 存放所有操作的队列  撤销功能将根据这个队列进行操作
        commends: [], // 存放操作的命令对应的映射表
        commendArray: [], // 存放所有的操作命令
        distroyArray: [] // 存放销毁的操作

    }
    // 注册操作命令
    const register = (commend) => {
        operationState.commendArray.push(commend)
        operationState.commends[commend.name] = (...args) => {
            // 注册对应按钮的执行方法
            const { redo, undo } = commend.exc(...args) // 可能一个命令里面会做多个操作 （1多操作）
            redo()
            // commend.exc() // 2单操作
            // 把每次操作都添加到队列中
            if (!commend.pushQueue) return
            // 操作0 ——> 操作1 ——> 操作2 ——> 撤销 3 ——> 操作4
            if (operationState.queue.length) {
                operationState.queue = operationState.queue.slice(0, operationState.index + 1)
            }
            // undo 才是具体要做的事
            operationState.queue.push({ redo, undo })
            operationState.index++
            console.log(operationState, 'operationState');

        }
    }
    register({
        name: 'undo',
        keyboard: 'ctrl+z',
        exc: () => {
            return { // 这里可以返回1多个操作
                redo() {
                    if (operationState.index === -1) return
                    const item = operationState.queue[operationState.index]
                    if (item && item.undo) {
                        item.undo()
                        operationState.index--
                    }
                }
            }

            // 2单个操作
            // console.log('撤销');

        }
    })
    register({
        name: 'del',
        pushQueue: true,
        exc: () => {
            const state = {
                before: JSON.parse(JSON.stringify(data.value.blocks)),
                after: foucsData.value.unfoucs
            }
            return {
                redo() {
                    data.value = { ...data.value, blocks: state.after }
                },
                undo() {
                    data.value = { ...data.value, blocks: state.before }
                }
            }
        }
    })
    register({
        name: 'ZindexUp',
        pushQueue: true,
        exc: () => {
            let before = JSON.parse(JSON.stringify(data.value.blocks))
            let after = (() => {
                const { foucs, unfoucs } = foucsData.value
                // 在未选中的 块中找到最大的zIndex                
                let maxUnfouc = unfoucs.sort((a, b) => a.index - b.index)
                // 可能会存在同层级的bug                
                foucs.forEach(block => {
                    block.index = maxUnfouc[0].index + 1
                })
                return data.value.blocks
            })()
            console.log(before, 'before', after);

            return {
                redo() {
                    data.value = { ...data.value, blocks: after }
                },
                undo() {
                    data.value = { ...data.value, blocks: before }
                }
            }
        }
    })
    register({
        name: 'ZindexDown',
        pushQueue: true,
        exc: () => {
            let before = JSON.parse(JSON.stringify(data.value.blocks))
            let after = (() => {
                const { foucs } = foucsData.value
                // 在未选中的 块中找到最大的zIndex  
                // 方法 1 将当前选中的一个一个的往下移动                             
                foucs.forEach(block => {
                    if (block.index - 1 < -1) {
                        block.index = 0
                    } else {
                        block.index = block.index - 1
                    }

                })
                // 方法2 将当前选中的 全部减 1 如果小于-0 就直接改为0 （画布有层级）  未选中的全部加1
                return data.value.blocks
            })()
            console.log(before, 'before', after);

            return {
                redo() {
                    data.value = { ...data.value, blocks: after }
                },
                undo() {
                    data.value = { ...data.value, blocks: before }
                }
            }
        }
    })
    register({
        name: 'redo',
        keyboard: 'ctrl+y',
        exc: () => {
            return {
                redo() {
                    const item = operationState.queue[operationState.index + 1]
                    if (item && item.redo) {
                        item.redo()
                        operationState.index++

                    }
                }
            }
        }
    })
    // 注册 拖动 操作之前 和 操作之后的 指令
    register({
        name: 'drag',
        pushQueue: true, // 是否需要将当前指令 添加到 存放所有操作的队列
        init() {
            beforeDrag = null
            const startDragComponent = () => {
                beforeDrag = JSON.parse(JSON.stringify(data.value.blocks))
            }
            // 拖砖之后需要出发点对应的指令
            const endDragComponent = () => operationState.commends.drag()
            event.on('startDragComponent', startDragComponent)
            event.on('endDragComponent', endDragComponent)


            return () => {
                event.off('startDragComponent', startDragComponent)
                event.off('endDragComponent', endDragComponent)
            }
        },
        exc() {
            // 即拖动后的块数据。  拖动前的块数据
            let before = beforeDrag;
            let after = data.value.blocks
            return {
                redo() {
                    // 默认 下一步
                    console.log('拖动');
                    data.value = { ...data.value, blocks: after }
                },
                undo() {
                    // 上一步
                    console.log('>>>>>>>>>beforeDrag', before);
                    console.log('撤销拖动');
                    data.value = { ...data.value, blocks: before }
                }
            }
        }
    })
    // 更新整个容器
    register({
        name: 'updateContainer',
        pushQueue: true,
        exc(newValue) {
            const state = {
                before: data.value,
                after: newValue
            }

            return {
                redo() {
                    data.value = state.after
                },
                undo() {
                    console.log('state.before', state.before);

                    data.value = state.before
                }
            }
        }
    })
    // 更新单个块
    register({
        name: 'updateBlock',
        pushQueue: true,
        exc(oldValue, newValue) {
            const state = {
                before: data.value.blocks,
                after: (() => {
                    const blocks = [...data.value.blocks]
                    // 先找到老的 然后替换
                    const index = data.value.blocks.indexOf(oldValue)
                    if (index === -1) return
                    blocks.splice(index, 1, newValue)
                    return blocks
                })()
            }
            return {
                redo() {
                    data.value = { ...data.value, blocks: state.after }
                },
                undo() {
                    data.value = { ...data.value, blocks: state.before }
                }
            }
        }

    })
    // 下载HTMl
    register({
        name: 'download',
        exc() {
            const htmlContent = getDomTemplate('low_page_dom');
            // 创建下载链接
            const downloadLink = document.createElement('a');
            downloadLink.href = 'data:text/html;charset=utf-8,' + encodeURI(htmlContent);
            downloadLink.download = 'export.html';
            return {
                redo() {
                    console.log('导出');
                    // 触发下载
                    document.body.appendChild(downloadLink);
                    downloadLink.click();
                    document.body.removeChild(downloadLink);
                }
            }
        }
    })
    register({
        name: 'export',
        exc() {
            // 获取HTML内容
            const htmlContent = getDomTemplate('low_page_dom');
            // 同时把所有选中的block 干掉
            const blocks = [...data.value.blocks]
            blocks.forEach(block => block.foucs = false)
            return {
                redo() {
                    data.value = { ...data.value, blocks: blocks }
                    event.emit('showPop', htmlContent)
                }
            }
        }
    })
        // 监听键盘事件
        // const keyboardEnevt = () => {

        //     const keydown = (e) => {
        //         const { ctrlKey, key } = e
        //         if (ctrlKey && key) {
        //             operationState.commendArray.forEach(({ name, keyboard }) => {
        //                 if ('ctrl+' + key === keyboard) {
        //                     operationState.commends[name]()
        //                     return
        //                 }
        //             })
        //         }
        //         e.preventDefault();
        //     }
        //     document.addEventListener('keydown', keydown)

        //     return () => {
        //         document.removeEventListener('keydown', keydown)
        //     }
        // }
        // 初始化
        ; (() => {
            // operationState.distroyArray.push(keyboardEnevt())
            operationState.commendArray.forEach(commend => {
                if (commend.init) {
                    const off = commend.init()
                    if (off) {
                        operationState.distroyArray.push(off)
                    }
                }
            })
        })()

    // 销毁函数
    onUnmounted(() => {
        return () => {
            operationState.distroyArray.forEach(off => off && off())
        }
    })
    const button = [{
        label: '撤销',
        handler: () => {
            operationState.commends.undo()
        }
    }, {
        label: '恢复上一次操作',
        handler: () => {
            operationState.commends.redo()
        }
    },
    {
        label: '上移',
        handler: () => {
            operationState.commends.ZindexUp()
        }
    },
    {
        label: '下移',
        handler: () => {
            operationState.commends.ZindexDown()
        }
    },
    {
        label: '删除',
        handler: () => {
            operationState.commends.del()
        }
    },
    {
        label: '导出',
        handler: () => {
            operationState.commends.export()
        }
    },
    {
        label: '下载',
        handler: () => {
            operationState.commends.download()
        }
    }]
    // 将 class 样式转换为内联样式，并合并现有的 style 属性
    // const convertClassToInlineStyle = (element) => {
    //     if (!element) return;

    //     // 获取元素的计算样式
    //     const computedStyle = window.getComputedStyle(element);
    //     console.log(computedStyle, 'computedStyle');

    //     // 获取现有的内联样式
    //     const existingStyle = element.getAttribute('style') || '';

    //     // 创建一个对象来存储合并后的样式
    //     const styleObject = {};

    //     // 将计算样式添加到 styleObject 中
    //     for (let i = 0; i < computedStyle.length; i++) {
    //         const property = computedStyle[i];
    //         styleObject[property] = computedStyle.getPropertyValue(property);
    //     }

    //     // 将现有的内联样式添加到 styleObject 中
    //     existingStyle.split(';').forEach(style => {
    //         if (style.trim()) {
    //             const [property, value] = style.split(':');
    //             styleObject[property.trim()] = value.trim();
    //         }
    //     });

    //     // 将合并后的样式应用为内联样式
    //     element.setAttribute('style', Object.entries(styleObject).map(([property, value]) => `${property}: ${value};`).join(' '));

    //     // 递归处理子元素
    //     Array.from(element.children).forEach(child => convertClassToInlineStyle(child));
    // }
    // 获取dom元素
    const getDomTemplate = (templateId) => {
        const element = document.getElementById(templateId);
        console.log(element, 'element');
        // 创建一个新的DOM元素用于存储HTML内容
        const tempDiv = document.createElement('div');

        // 将目标元素的内容克隆到临时div
        tempDiv.appendChild(element.cloneNode(true));

        // convertClassToInlineStyle(tempDiv);
        // 获取HTML内容
        return tempDiv.innerHTML;
    }
    return {
        button,
        updateBlock: operationState.commends.updateBlock,
        updateContainer: operationState.commends.updateContainer
    }
}   